/*********************************************************************\
*
*                  (c) lkc
*                  All Rights Reserved. lkc Confidential
*
\*********************************************************************/
/*********************************************************************\
*   Title                      :
*
*   Module Description         :
*
*   Author                     : lkc
*
*   Created                    : 2018-7-3
*
\*********************************************************************/

#include "ProtocolPod205.h"
#ifdef POD_IS_205
#include <math.h>
#include "CamGainControl.h"
#include "ImageDetect.h"
#include "CamControl.h"
#include "DisplayControl.h"
#include "UtilityTH.h"
#include "FocusControl.h"

ProtocolPod205 ProtocolPod205::m_Instance;//静态成员变量在类中仅仅是声明，没有定义，所以要在类的外面定义，实际上是给静态成员变量分配内存。

int ProtocolPod205::CycleSendOnce()
{
    int frameLenght = 50;
    unsigned char frameToSendCycle[frameLenght];
    memset(frameToSendCycle,0,frameLenght);
    frameToSendCycle[0] = HEAD1;
    frameToSendCycle[1] = HEAD2_CYCLE;
    frameToSendCycle[2] = NORMAL_CYCLE;   //数据状态
    frameToSendCycle[3] = focusCtl.GetSelfCheckState()?0x00:0x01;   //自检状态
    //frameToSendCycle[3] = ProtocolMCU::GetInstance().GetSelfCheckState()?0x00:0x01;   //自检状态
    OutMode mode = GetOutMode();
    unsigned char modeData;
    if(mode == OutMode::ORIGINAL)
    {
        modeData = 0x01;
    }
    else if(mode == OutMode::ENHANCE)
    {
        modeData = 0x02;
    }
    else
    {
        modeData = 0x03;
    }

    frameToSendCycle[4] = modeData;   //输出模式
    frameToSendCycle[5] = CamControl::GetInstance().GetWorkMode()?0x01:0x02;   //运行模式 GetWorkMode

    frameToSendCycle[6] = static_cast<unsigned char>((focusCtl.GetViewField()*10));
//    frameToSendCycle[6] = static_cast<unsigned char>((ProtocolMCU::GetInstance().GetViewField()*10));

    std::vector <cv::Point2f> points = ImageDetect::GetInstance().GetObjectPoints();
    //字节长度最多十个点
    unsigned int num = points.size();
    if(num > OBJECT_NUM_MAX)
    {
        num = OBJECT_NUM_MAX;
    }
    frameToSendCycle[7] = num;
    int i = 8;
    for(unsigned int j = 0; j < num; j++)
    {
        int xCode = static_cast<int>(points[j].x*10);
        int yCode = static_cast<int>(points[j].y*10);
        //x坐标，浮点数保留一位小数
        frameToSendCycle[i++] = xCode&0xFF;
        frameToSendCycle[i++] = (xCode>>8)&0xFF;
        //y坐标
        frameToSendCycle[i++] = yCode&0xFF;
        frameToSendCycle[i++] = (yCode>>8)&0xFF;
    }
    for( ; i < 48 ; i++)
    {
        frameToSendCycle[i] = 0;
    }
    frameToSendCycle[48] = CheckSum(frameToSendCycle+2,frameLenght-4);       //校验和
    frameToSendCycle[49] = 0xFB;       //帧尾
    int ret = Send(frameToSendCycle,frameLenght);
    if (ret < 0)
    {
        printf("ProtocolPod write data error!\n");
    }
    return ret;
}

void ProtocolPod205::ExtractData(const unsigned char *data, int nLength)
{
    m_bufferTempMtx.lock();
    m_bufferTemp.insert(m_bufferTemp.end(),data,data+nLength);
    while( m_bufferTemp.size() >= FRAME_LENGTH_RECEIVE)
    {
        auto iter = m_bufferTemp.begin();
        if (*iter != HEAD1)
        {
            //如果数据开始不是头，则删除数据
            m_bufferTemp.erase(iter);
            continue;
        }
        if(*(iter+1) != HEAD2_EVENT)
        {
            m_bufferTemp.erase(iter);
            continue;
        }
        if(*(iter+FRAME_LENGTH_RECEIVE-1) != END)
        {
            m_bufferTemp.erase(iter,iter+2);
            continue;
        }

        unsigned char sum = CheckSum(iter+2,3);
        if(*(iter+FRAME_LENGTH_RECEIVE-2) != sum)
        {
            m_bufferTemp.erase(iter,iter+2);
            continue;
        }
        EventReceiveFrameParse();
        m_bufferTemp.erase(iter,iter+FRAME_LENGTH_RECEIVE);
    }
    m_bufferTempMtx.unlock();
}

void ProtocolPod205::EventReceiveFrameParse()
{
    m_funcCodeReceive = m_bufferTemp[2];
    //    printf("commandReceive: %x\n",m_commandReceive);
    m_commandReceive = m_bufferTemp[3];
    m_dataReceive = m_bufferTemp[4];
    switch (m_funcCodeReceive)
    {
    case 0xC0:
        SelfCheckParse();
        break;
    case 0xC1:
        GainParse();
        break;
    case 0xC2:
        FoucsParse();
        break;
    case 0xC3:
        ContrastParse();
        break;
    case 0xC4:
        OutModeParse();
        break;
    case 0xC5:
        WorkModeParse();
        break;
    default:
        break;
    }
}

void ProtocolPod205::SelfCheckParse()
{
    if(m_commandReceive == 0x00)//启动相机自检
    {
        focusCtl.MotoSelfCheck();
//        ProtocolMCU::GetInstance().MotoSelfCheck();
    }
}

void ProtocolPod205::GainParse()
{
    switch(m_commandReceive)
    {
    case 0x01://增加增益
        CamGainControl::GetInstance().IncGain();
        break;
    case 0x02://减小增益
        CamGainControl::GetInstance().DecGain();
        break;
    case 0x10://增益自动调节
        CamGainControl::GetInstance().SetGainAutoMode(true);
        break;
    default:
        return;
    }
}

void ProtocolPod205::FoucsParse()
{
    switch(m_commandReceive)
    {
    case 0x01://增大视场角
        focusCtl.DecFocus();
//        ProtocolMCU::GetInstance().DecFocus();
        break;
    case 0x02://减小视场角
        focusCtl.IncFocus();
//        ProtocolMCU::GetInstance().IncFocus();
        break;
    case 0x10://设置视场角绝对值
        focusCtl.SetView(m_dataReceive/10.0);
//        ProtocolMCU::GetInstance().SetView(m_dataReceive/10.0);
        break;
    default:
        break;
    }
}

void ProtocolPod205::ContrastParse()
{
    switch(m_commandReceive)
    {
    case 0x01://增加对比度
        IncContrast();
        break;
    case 0x02://减小对比度
        DecContrast();
        break;
    default:
        return;
    }
}

void ProtocolPod205::OutModeParse()
{
    switch(m_commandReceive)
    {
    case 0x01://原图输出模式
        SetOutMode(OutMode::ORIGINAL);
        break;
    case 0x02://增强输出模式
        SetOutMode(OutMode::ENHANCE);
        break;
    case 0x03://信息叠加模式
        SetOutMode(OutMode::SUPERPOSITION);
        break;
    case 0x20://隐藏十字中心线
        SetCrossMode(false);
        break;
    case 0x21://显示十字中心线
        SetCrossMode(true);
        break;
    default:
        return;
    }
}

void ProtocolPod205::WorkModeParse()
{
    switch(m_commandReceive)
    {
    case 0x01://工作模式
        CamControl::GetInstance().SetWorkMode(true);
        break;
    case 0x02://待机模式，切断CCD与调焦系统
        CamControl::GetInstance().SetWorkMode(false);
        break;
    default:
        return;
    }
}

#endif //ifdef POD_IS_205

/********************************************************************\
 *
 * REVISION RECORDS
 *
\*********************************************************************/
/*********************************************************************/
/*
 *
 *
 *
\*********************************************************************/
/*------------------------------The End------------------------------*/
